package com.authorization.demo.controller;

import com.authorization.demo.entity.MenuRole;
import com.authorization.demo.exception.TokenException;
import com.authorization.demo.request.FindMenuRequest;
import com.authorization.demo.entity.Menu;
import com.authorization.demo.request.MenuDirectory;
import com.authorization.demo.request.MenuTypeDirectory;
import com.authorization.demo.service.MenuService;
import com.authorization.demo.utils.TokenUtils;
import com.authorization.demo.vo.R;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@CrossOrigin //开放跨域访问
@RestController
@RequestMapping("/menu")
@Api(tags = "菜单管理")
public class MenuController {

    @Resource
    private MenuService menuService;

    //配合接口做的测试
    @ApiOperation("全部查询的简单测试接口")
    @GetMapping("/findAllTest")
    public R findAll(@RequestParam String token) {
        try {
            TokenUtils.powerCheck(token, "查询菜单");
        } catch (TokenException tokenException) {
            return R.ok().setCode(tokenException.getCode()).setMessage(tokenException.getMessage());
        }
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("IS_DELETE",1);
       /* //queryWrapper.orderByDesc("CREATE_DATE");
        IPage<Menu> menuPage = new Page<>(1, 20);//参数一是当前页，参数二是每页个数
        menuPage = menuService.page(menuPage, queryWrapper);
        List<Menu> listByPage = menuPage.getRecords();*/
        List<Menu> listByPage = menuService.list(queryWrapper);
        return R.ok().data("listByPage", listByPage);
    }
    //菜单管理首页的查询
    @ApiOperation("带条件的分页查询")
    @PostMapping("/findList")
    public R findList(@RequestBody FindMenuRequest findRequest,@RequestParam String token) {
        try {
            TokenUtils.powerCheck(token, "查询菜单");
        } catch (TokenException tokenException) {
            return R.ok().setCode(tokenException.getCode()).setMessage(tokenException.getMessage());
        }
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
//        IPage<Menu> menuPage;

        if (findRequest.menuName != null) {
            queryWrapper.like("MENU_NAME", findRequest.menuName);
        }
        if (findRequest.status != 0) {
            queryWrapper.eq("STATUS", findRequest.status);
        }
        if (findRequest.type != 0) {
            queryWrapper.eq("TYPE", findRequest.type);
        }
       /* if (findRequest.current != 0) {
            menuPage = new Page<>(findRequest.current, 20);
        } else {
            menuPage = new Page<>(1, 20);
        }*/
        queryWrapper.eq("IS_DELETE",1);

//

        List<Menu> MenuList = menuService.list(queryWrapper);
        return R.ok().data("MenuList", MenuList);

    }


    //新增菜单
       /*  1) 用户首先要选择新增菜单的类别，必须要选。
        2) 输入菜单名，要求在20个字符以内，而且是必须要输入的选项；
        3) 选择上级菜单，从下拉框中选择，菜单大小顺序为：目录>菜单>功能，可以不选；
        4) 选择状态，从下拉框中选择，而且状态只有“有效”和“无效”这两种，可以不选；
        5) 输入描述，要求在500个字符以内，选填；
        6) 输入排序号，选填；
        7) 输入地址，当类别为“菜单”的时候，必须输入URL地址；
        输入菜单标识，作为标识码，当类别为“功能”的时候必须输入；*/
    @ApiOperation("新增菜单")
    @PostMapping("/createMenu")
    public R createMenu(@RequestBody Menu menu,@RequestParam String token) {
        try {
            TokenUtils.powerCheck(token, "新增菜单");
        } catch (TokenException tokenException) {
            return R.ok().setCode(tokenException.getCode()).setMessage(tokenException.getMessage());
        }
        //菜单已经存在，判断该菜单是否被逻辑删除
        if(menuService.findMenuexist(menu.getMenuName())){
            Menu existmenu = menuService.getById(menu.getMenuName());
            if(existmenu.getIsDelete()==1) {
                return R.ok().setCode(403).setMessage("菜单已存在");
            }
            else{
                menuService.updateById(menu);
                return R.ok().setMessage("已存在的菜单已被覆盖");

            }
        }
        else {
            menuService.save(menu);
            return R.ok();
        }

    }


    //批量删除菜单
    @ApiOperation("批量删除菜单")
    @PostMapping("/deleteMenus")
    public R deleteMenus(@RequestParam("menuNames") String[] menuNames,@RequestParam String token) {
        try {
            TokenUtils.powerCheck(token, "删除菜单");
        } catch (TokenException tokenException) {
            return R.ok().setCode(tokenException.getCode()).setMessage(tokenException.getMessage());
        }
        //将待删除的菜单名封装成一个列表
        List<String>menuList= Arrays.asList(menuNames);

        //开始遍历待删除的菜单名
        for (int i = 0; i < menuList.size(); i++) {
            //获取菜单名
            String menuName= menuList.get(i);
            R r = menuService.delmenu(menuName);
            if(r.getCode()!=200 || r.getMessage()!="成功"){
                return R.error().setMessage("批量删除出现问题");
            }
        }
        return R.ok();
    }

    /*//批量删除菜单
    @ApiOperation("批量删除菜单")
    @PostMapping("/deleteMenu")
    public R deleteMenus(@RequestBody List<String> menuNames) {
        if (menuService.removeByIds(menuNames)) {
            return R.ok();
        }
        return R.error().setMessage("批量删除菜单出现问题");
    }*/


    //删除菜单
    @ApiOperation("删除菜单")
    @PostMapping("/deleteMenu")
    public R delete(@RequestParam String menuName,@RequestParam String token) {
        try {
            TokenUtils.powerCheck(token, "删除菜单");
        } catch (TokenException tokenException) {
            return R.ok().setCode(tokenException.getCode()).setMessage(tokenException.getMessage());
        }
        return menuService.delmenu(menuName);
    }

    //修改菜单
    @ApiOperation("修改菜单")
    @PostMapping("/alterMenu")
    public R alterMenu(@RequestBody Menu menu,@RequestParam String token) {
        try {
            TokenUtils.powerCheck(token, "修改菜单");
        } catch (TokenException tokenException) {
            return R.ok().setCode(tokenException.getCode()).setMessage(tokenException.getMessage());
        }
        if (menuService.updateById(menu)) {
            return R.ok();
        }
        return R.error().setMessage("修改出现问题");
    }

    //嵌套获取菜单列表的树状图
    @ApiOperation("嵌套获取菜单列表的树状图")
    @GetMapping("/ViewAllMenu")
    public R ViewAllMenu(@RequestParam String token) {
        try {
            TokenUtils.powerCheck(token, "分配权限");
        } catch (TokenException tokenException) {
            return R.ok().setCode(tokenException.getCode()).setMessage(tokenException.getMessage());
        }
        /* //嵌套的菜单目录实体类
            public class MenuDirectory {
                private String menuName;
                private List<MenuDirectory> menuDirectories;
        }*/
        //查出数据库所有的菜单记录实体
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("IS_DELETE",1);

        List<Menu> menuList = menuService.list(queryWrapper);
        //menuDirectoryList中存放的是各个一级目录的菜单名和其对应的子目录的嵌套实体的一个列表

        List<MenuDirectory> menuDirectoryList = new ArrayList<>();
        //将所有的一级目录的菜单名对应的menuDirectory实体全部存入到list中
        for(Menu menu:menuList){
            //从菜单类型为1的类型开始嵌套，将其封装到自定义的数据类型中
            if(menu.getType()==1){
                MenuDirectory menuDirectory = new MenuDirectory();
                //将一级菜单名存放在自定义的嵌套实体中
                menuDirectory.setMenuName(menu.getMenuName());
                //获取二级菜单名列表
                List<String> subMenunameList = menuService.findSubmenuName(menu.getMenuName());
                //定义存放的一级菜单对应的二级菜单的嵌套实体的list
                List<MenuDirectory> submenuDirectories = new ArrayList<>();
                for(String subMenuname : subMenunameList){
                    //定义二级菜单的嵌套实体对象
                    MenuDirectory subMenuDirectory = new MenuDirectory();
                    subMenuDirectory.setMenuName(subMenuname);

                    //开始在二级目录中嵌套三级目录
                    List<String> subsubMenunamelist =menuService.findSubmenuName(subMenuname);
                    List<MenuDirectory> subsubmenuDirectories = new ArrayList<>();
                    for(String subsubMenuname : subsubMenunamelist){
                        MenuDirectory subsubMenuDirectory = new MenuDirectory();
                        subsubMenuDirectory.setMenuName(subsubMenuname);
                        subsubmenuDirectories.add(subsubMenuDirectory);
                    }
                    subMenuDirectory.setMenuDirectories(subsubmenuDirectories);
                    submenuDirectories.add(subMenuDirectory);

                }
                //将一级菜单的子菜单嵌套列表存放在自定义的嵌套实体内
                menuDirectory.setMenuDirectories(submenuDirectories);
                //将自定义的嵌套实体放入list中
                menuDirectoryList.add(menuDirectory);
            }
        }
        return R.ok().data("menuDirectoryList",menuDirectoryList);
    }

    //按类型嵌套获取菜单列表的树状图
    @ApiOperation("按类型嵌套获取菜单列表的树状图")
    @GetMapping("/FindAllMenu")
    public R FindAllMenu(@RequestParam String token) {
       
        /* //嵌套的菜单目录实体类
            public class MenuDirectory {
                private int type;
                private String menuName;
                private List<MenuDirectory> menuDirectories;
        }*/
        //查出数据库所有的菜单记录实体
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("IS_DELETE",1);

        List<Menu> menuList = menuService.list(queryWrapper);
        //menuDirectoryList中存放的是各个一级目录的菜单名和其对应的子目录的嵌套实体的一个列表

        List<MenuTypeDirectory> menuTypeDirectoryList = new ArrayList<>();
        //将所有的一级目录的菜单名对应的menuDirectory实体全部存入到list中
        for(Menu menu:menuList){
            //从菜单类型为1的类型开始嵌套，将其封装到自定义的数据类型中
            if(menu.getType()==1){
                MenuTypeDirectory menuTypeDirectory = new MenuTypeDirectory();
                //将一级菜单名存放在自定义的嵌套实体中
                menuTypeDirectory.setMenuName(menu.getMenuName());
                menuTypeDirectory.setUrl(menu.getUrl());
                menuTypeDirectory.setType(menu.getType());
                //获取二级菜单名列表
                List<String> subMenunameList = menuService.findSubmenuName(menu.getMenuName());
                //定义存放的一级菜单对应的二级菜单的嵌套实体的list
                List<MenuTypeDirectory> submenuDirectories = new ArrayList<>();
                for(String subMenuname : subMenunameList){
                    //定义二级菜单的嵌套实体对象
                    MenuTypeDirectory subMenuDirectory = new MenuTypeDirectory();
                    subMenuDirectory.setMenuName(subMenuname);
                    subMenuDirectory.setUrl(menuService.getById(subMenuname).getUrl());
                    subMenuDirectory.setType(menuService.getById(subMenuname).getType());
                    //开始在二级目录中嵌套三级目录
                    List<String> subsubMenunamelist =menuService.findSubmenuName(subMenuname);
                    List<MenuTypeDirectory> subsubmenuDirectories = new ArrayList<>();
                    for(String subsubMenuname : subsubMenunamelist){
                        MenuTypeDirectory subsubMenuDirectory = new MenuTypeDirectory();
                        subsubMenuDirectory.setMenuName(subsubMenuname);
                        subsubMenuDirectory.setUrl(menuService.getById(subsubMenuname).getUrl());
                        subsubMenuDirectory.setType(menuService.getById(subsubMenuname).getType());
                        subsubmenuDirectories.add(subsubMenuDirectory);
                    }
                    subMenuDirectory.setMenuDirectories(subsubmenuDirectories);
                    submenuDirectories.add(subMenuDirectory);

                }
                //将一级菜单的子菜单嵌套列表存放在自定义的嵌套实体内
                menuTypeDirectory.setMenuDirectories(submenuDirectories);
                //将自定义的嵌套实体放入list中
                menuTypeDirectoryList.add(menuTypeDirectory);
            }
        }
        return R.ok().data("menuDirectoryList",menuTypeDirectoryList);
    }


}
